package com.example.demo.common;

import com.example.demo.game.*;
import com.example.demo.model.Userinfo;
import com.example.demo.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.jws.soap.SOAPBinding;
import java.io.IOException;

@Component
public class TextGame extends TextWebSocketHandler {
    private ObjectMapper objectMapper=new ObjectMapper();

    @Autowired
    private RoomManager roomManager;

    @Autowired
    private GetUserLoginMatch getUserLoginMatch;

    @Autowired
    private UserService userService;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //判断是否登录
        Userinfo userinfo = (Userinfo) session.getAttributes().get(AppValues.USER_KEY);
        RespReadyGame respReadyGame =new RespReadyGame();
        System.out.println("当前用户为"+userinfo.getUserid());
        if(userinfo==null) {
            System.out.println("未登录");
            respReadyGame.setOk(false);
            respReadyGame.setReason("未登录");
            respReadyGame.setMessage("noReady");//未就绪
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
            return;
        }

        //判断是否进入对战房间
        Room room=roomManager.getRoomByUserId(userinfo.getUserid());
        if(room==null) {
            //没有进入对战房间
            System.out.println("未进入对战匹配");
            respReadyGame.setOk(false);
            respReadyGame.setReason("未进入对战匹配");
            respReadyGame.setMessage("noReady");//未就绪
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
            return;
        }
        if(getUserLoginMatch.getFromGameHall(userinfo.getUserid())!=null
                ||getUserLoginMatch.getFromGameGame(userinfo.getUserid())!=null) {//表示在匹配阶段已登录或对战阶段已登录
            respReadyGame.setOk(true);
            respReadyGame.setReason("禁止双开");
            respReadyGame.setMessage("noshuang");//未就绪
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
            session.close();
        }
        getUserLoginMatch.enterGameGame(userinfo.getUserid(),session);//判断完后加入对战状态
        synchronized (room) {//防止两个同时进入都判空,所以加锁
            if(room.getUserinfo1()==null) {//他等于空就说明两个都没加入,先加入为先手
                room.setUserinfo1(userinfo);
                room.setWhiteUser(userinfo.getUserid());
                System.out.println("先手玩家为"+userinfo.getUserid());
                System.out.println("玩家一准备就绪");
            }else if(room.getUserinfo2()==null) {
                room.setUserinfo2(userinfo);
                System.out.println("玩家二准备就绪");
                noticeGameReady(room,room.getUserinfo1().getUserid(),room.getUserinfo2().getUserid());//分别返回响应
                noticeGameReady(room,room.getUserinfo2().getUserid(),room.getUserinfo1().getUserid());
            }
        }
        System.out.println("建立连接");
    }

    /**
     * 向客户端返回玩家准备就绪的响应
     * @param room
     * @param userid
     * @param userid1
     * @throws IOException
     */
    private void noticeGameReady(Room room, Integer userid, Integer userid1) throws IOException {
        RespReadyGame respReadyGame =new RespReadyGame();
        respReadyGame.setMessage("gameReady");//准备就绪的约定
        respReadyGame.setOk(true);
        respReadyGame.setRoomid(room.getRoomId());
        respReadyGame.setUserid1(userid);
        respReadyGame.setUserid2(userid1);
        respReadyGame.setWhiteUser(room.getWhiteUser());
        WebSocketSession session=getUserLoginMatch.getFromGameGame(userid);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Userinfo userinfo = (Userinfo) session.getAttributes().get(AppValues.USER_KEY);
        if(userinfo==null) {
            System.out.println("未登录");
        }
        Room room=roomManager.getRoomByUserId(userinfo.getUserid());//获取到对战房间
        room.putchess(message.getPayload());

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        Userinfo userinfo= (Userinfo) session.getAttributes().get(AppValues.USER_KEY);
        RespReadyGame respReadyGame=new RespReadyGame();
        if(userinfo==null) {
            System.out.println("未登录");
            respReadyGame.setOk(false);
            respReadyGame.setReason("未登录");
            respReadyGame.setMessage("noReady");//未就绪
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
            return;
        }
        if(session==getUserLoginMatch.getFromGameGame(userinfo.getUserid())) {
            getUserLoginMatch.exitGameGame(userinfo.getUserid());//下线从对战状态删除
        }
        System.out.println("连接错误");

        System.out.println("用户退出");
        //连接错误直接判定对手胜利
        noticeThatUserWin(userinfo);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Userinfo userinfo= (Userinfo) session.getAttributes().get(AppValues.USER_KEY);
        RespReadyGame respReadyGame=new RespReadyGame();
        if(userinfo==null) {
            System.out.println("未登录");
            respReadyGame.setOk(false);
            respReadyGame.setReason("未登录");
            respReadyGame.setMessage("noReady");//未就绪
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respReadyGame)));
            return;
        }
        if(session==getUserLoginMatch.getFromGameGame(userinfo.getUserid())) {
            getUserLoginMatch.exitGameGame(userinfo.getUserid());//下线从对战状态删除
        }
        System.out.println("关闭连接");

        //连接异常关闭直接判定对手胜利
        System.out.println("用户退出");
        noticeThatUserWin(userinfo);
    }

    /**
     * 处理对手或自己异常掉线和错误
     * @param userinfo
     */
    private void noticeThatUserWin(Userinfo userinfo) throws IOException {
        //通过当前登录的用户获取房间
       Room room=  roomManager.getRoomByUserId(userinfo.getUserid());
       if(room==null) {//说明房间已经销毁
           System.out.println("房间已经销毁");
           return;
       }
       //获取对手用户
       Userinfo thatuser=userinfo==room.getUserinfo1()?room.getUserinfo2():room.getUserinfo1();
       //获取对手用户的websocket
       WebSocketSession session= getUserLoginMatch.getFromGameGame(thatuser.getUserid());
       if(session==null) {
           System.out.println("玩家已下线");
           return;
       }
       RespGame respGame =new RespGame();
       respGame.setWinner(thatuser.getUserid());
       respGame.setMessage("putChess");
       respGame.setUserid(thatuser.getUserid());
       userService.upGameadd(thatuser.getUserid());
       userService.upGamedel(userinfo.getUserid());
       session.sendMessage(new TextMessage(objectMapper.writeValueAsString(respGame)));
    }
}
